﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Qero.ChartPoint
{
    class MetaUnit
    {
        /// <summary> Построение полной коллекции чартов
        /// </summary>
        public static Charter BuildCharter()
        {
            Charter outCharter = new Charter();

            outCharter.ChartSet = SelectChartList();

            if (outCharter.ChartSet.Count > 0)
            {
                List<ChartField> allFields = SelectFieldList();

                foreach (ChartTable currChart in outCharter.ChartSet)
                {
                    currChart.FieldSet = (from t in allFields where t.chartUid == currChart.chartUid select t).ToList();
                }

                outCharter.ChartSet[0].chartMake = true;
            }
            if (outCharter.ChartSet.Count > 1)
                outCharter.ChartSet[outCharter.ChartSet.Count - 1].chartMake = false;

            return outCharter;
        }

        /// <summary> Чтение из БД и построение списка чартов,
        /// либо чарта в единственном числе, если передать его Guid в качестве аргумента
        /// </summary>
        /// <param name="exactCharter">Guid единичного чарта для возврата</param>
        public static List<ChartTable> SelectChartList(Guid exactChart = new Guid())
        {
            DataQuarkLine chartData = GetKindQuark(CPTable.Chart, exactChart);
            chartData.AddSubQuark();
            chartData.AddImagQuark();
            chartData.AddFileQuark();

            List<DataQuarkLine> selectListData = ThisAddIn.dbControl.TableSelect(chartData);

            List<ChartTable> selectList = new List<ChartTable>();

            foreach (DataQuarkLine dataLine in selectListData)
            {
                ChartTable lineChart = BuildChartTable(dataLine);
                if (lineChart != null) selectList.Add(lineChart);
            }

            return selectList;
        }

        /// <summary> Чтение из БД и построение списка полей,
        /// который может быть ограничен полями выбранного чарта,
        /// либо поля в единственном числе, если передать его Guid в качетсве аргумента
        /// </summary>
        /// <param name="chartUid">Guid чарта, поля которого будут возвращены списком</param>
        /// <param name="exactField">Guid поля, которое будет единственное передано в список</param>
        public static List<ChartField> SelectFieldList(Guid chartUid = new Guid(), Guid exactField = new Guid())
        {
            DataQuarkLine fieldData = GetKindQuark(CPTable.Field, exactField);
            fieldData.AddUidQuark(chartUid, chartUid != Guid.Empty, CPTable.Chart);
            fieldData.AddTypeQuark();
            fieldData.AddEnumQuark();

            List<DataQuarkLine> selectListData = ThisAddIn.dbControl.TableSelect(fieldData);

            List<ChartField> selectList = new List<ChartField>();

            foreach (DataQuarkLine dataLine in selectListData)
            {
                ChartField lineField = BuildChartField(dataLine);
                if (lineField != null) selectList.Add(lineField);
            }

            return selectList;
        }

        /// <summary> Инициализация кварка для выполнения операций с данными
        /// </summary>
        /// <param name="tableKind">Вид табличных данных кварка</param>
        /// <param name="exactUid">Значение основного идентификатора</param>
        private static DataQuarkLine GetKindQuark(CPTable tableKind, Guid exactUid)
        {
            DataQuarkLine quarkData = new DataQuarkLine();
            quarkData.dataTable = tableKind;
            quarkData.AddUidQuark(exactUid, exactUid != Guid.Empty);
            quarkData.AddNameQuark();

            return quarkData;
        }

        /// <summary> Обновление данных заданного чарта в БД
        /// </summary>
        /// <param name="updChart">Обновляемый чарт</param>
        public static void UpdateChart(ChartTable updChart)
        {
            bool chartUpdated = (updChart.chartUid != Guid.Empty);

            if (!chartUpdated) updChart.chartUid = Guid.NewGuid();

            DataQuarkLine chartData = new DataQuarkLine();
            chartData.dataTable = CPTable.Chart;
            chartData.AddUidQuark(updChart.chartUid, chartUpdated);

            if (!updChart.chartDir.Equals(updChart.newItem.chartDir))
                chartData.AddSubQuark(updChart.newItem.chartDir);
            if (!updChart.chartName.Equals(updChart.newItem.chartName))
                chartData.AddNameQuark(updChart.newItem.chartName);
            if (!updChart.filesApp.Equals(updChart.newItem.filesApp))
                 chartData.AddFileQuark(Charter.GetYesno(updChart.newItem.filesApp));

            if (ThisAddIn.dbControl.TableSet(chartData, chartUpdated) > 0) updChart.EditIsOver();
        }

        /// <summary> Обновление данных заданного поля чарта
        /// </summary>
        /// <param name="updField">Обновляемое поле</param>
        /// <param name="chartUid">Guid чарта, которому принадлежит поле</param>
        public static void UpdateField(ChartField updField, Guid chartUid)
        {
            bool fieldUpdated = (updField.fieldUid != Guid.Empty);

            if (!fieldUpdated) updField.fieldUid = Guid.NewGuid();

            DataQuarkLine fieldData = new DataQuarkLine();
            fieldData.dataTable = CPTable.Field;            

            fieldData.AddUidQuark(chartUid, fieldUpdated, CPTable.Chart);
            fieldData.AddUidQuark(updField.fieldUid, fieldUpdated);

            if (!updField.fieldName.Equals(updField.newItem.fieldName))
                fieldData.AddNameQuark(updField.newItem.fieldName);
            if (!updField.fieldType.Equals(updField.newItem.fieldType))
                fieldData.AddTypeQuark((int)updField.newItem.fieldType);
            if ((updField.newItem.fieldType == CFType.PICK) && (!updField.EnumOptions.Equals(updField.newItem.EnumOptions)))
                fieldData.AddEnumQuark(BaseUnit.StringFrOpt(updField.newItem.EnumOptions));
            else if (((updField.newItem.fieldType == CFType.LOOK) || (updField.newItem.fieldType == CFType.MANY)) && (!updField.EnumLookups.Equals(updField.newItem.EnumLookups)))
                fieldData.AddEnumQuark(BaseUnit.StringFrOpt(updField.newItem.EnumLookups));

            if (ThisAddIn.dbControl.TableSet(fieldData, fieldUpdated) > 0) updField.EditIsOver();
        }

        /// <summary> Формирование чарта из табличных данных (кварка)
        /// </summary>
        /// <param name="tableQuark">Кварк с табличными данными</param>
        public static ChartTable BuildChartTable(DataQuarkLine tableQuark)
        {
            tableQuark.dataTable = CPTable.Chart;

            Guid chartUid = tableQuark.GetUidQuark();

            if (chartUid == Guid.Empty) return null;

            ChartTable chartTable = new ChartTable();
            chartTable.chartUid = chartUid;
            chartTable.chartDir = tableQuark.GetSubQuark();
            chartTable.chartName = tableQuark.GetNameQuark();
            chartTable.filesApp = Charter.GetYesnoText(tableQuark.GetFileQuark());
            chartTable.ReadyToEdit();

            return chartTable;
        }

        /// <summary> Формирование поля из табличных данных (кварка)
        /// </summary>
        /// <param name="fieldQuark">Кварк с табличными данными</param>
        public static ChartField BuildChartField(DataQuarkLine fieldQuark)
        {
            fieldQuark.dataTable = CPTable.Field;

            Guid fieldUid = fieldQuark.GetUidQuark();

            if (fieldUid == Guid.Empty) return null;

            ChartField chartField = new ChartField();
            chartField.fieldUid = fieldUid;
            chartField.chartUid = fieldQuark.GetUidQuark(CPTable.Chart);
            chartField.fieldName = fieldQuark.GetNameQuark();
            chartField.fieldType = (CFType)fieldQuark.GetTypeQuark();
            if (chartField.fieldType == CFType.PICK)
                chartField.EnumOptions = BaseUnit.OptionsStr(fieldQuark.GetEnumQuark());
            if (chartField.fieldType == CFType.LOOK || chartField.fieldType == CFType.MANY)
                chartField.EnumLookups = BaseUnit.OptionsUid(fieldQuark.GetEnumQuark());
            chartField.ReadyToEdit();

            return chartField;
        }
    }
}
